package com.tenchael.iblog.web.controller;

import com.google.common.base.Preconditions;
import com.tenchael.iblog.bussiness.UserBussiness;
import com.tenchael.iblog.domain.User;
import com.tenchael.iblog.exceptions.BussinessException;
import com.tenchael.iblog.service.UserService;
import com.tenchael.iblog.utils.MixAll;
import com.tenchael.iblog.web.wrapper.LoginDto;
import com.tenchael.iblog.web.wrapper.RegisterDto;
import com.tenchael.iblog.web.wrapper.RestWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import static com.tenchael.iblog.commons.Contants.ErrorCode.*;
import static com.tenchael.iblog.commons.Contants.RegPattern.*;

/**
 * Created by tengzhizhang on 2017/12/25.
 */
@RestController
public class UserController extends BaseController {

	private static final Logger LOGGER = LogManager.getLogger(UserController.class);

	@Autowired
	private UserService userService;

	@Autowired
	private UserBussiness userBussiness;

	@RequestMapping("/user/{id}")
	public RestWrapper<User> findUserById(@PathVariable("id") Long id) {
		return new RestWrapper<>(userService.findById(id));
	}

	@PostMapping("/login")
	public RestWrapper<Boolean> login(@RequestBody LoginDto loginDto) {
		try {
			Preconditions.checkArgument(loginDto != null, "have no parameter received");
			Preconditions.checkArgument(StringUtils.isNotBlank(loginDto.getAccount()), "account can not be null or blank");
			Preconditions.checkArgument(StringUtils.isNotBlank(loginDto.getPassword()), "password can not be null or blank");
			boolean valid = userBussiness.login(loginDto.getAccount(), loginDto.getPassword());
			if (valid) {
				return new RestWrapper<>(true);
			}
			return new RestWrapper<>(UNKOWN_ERROR, "login failed");
		} catch (IllegalArgumentException e) {
			LOGGER.warn("login parameters error: {}", e.getMessage());
			return new RestWrapper<>(PARAM_ERROR, e.getMessage());
		} catch (BussinessException e) {
			LOGGER.warn("login occurs error: {}", e.getMessage());
			return new RestWrapper<>(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("login occurs system error", e);
			return new RestWrapper<>(SYSTEM_ERROR, "system is busy, please try later");
		}
	}

	@PostMapping("/register")
	public RestWrapper<Boolean> register(@RequestBody RegisterDto registerDto) {
		try {
			//parameters validation
			Preconditions.checkArgument(registerDto != null, "have no parameter received");
			Preconditions.checkArgument(registerDto.getUsername() != null, "username can not be null");
			Preconditions.checkArgument(registerDto.getPassword() != null, "password can not be null");
			Preconditions.checkArgument(registerDto.getEmail() != null, "email can not be null");
			Preconditions.checkArgument(MixAll.isMatchedPattern(registerDto.getUsername(), USERNAME_PATTERN),
					String.format("username '%s' is illegal", registerDto.getUsername()));
			Preconditions.checkArgument(MixAll.isMatchedPattern(registerDto.getPassword(), PASSWORD_PATTERN),
					"password is illegal");
			Preconditions.checkArgument(MixAll.isMatchedPattern(registerDto.getEmail(), EMAIL_PATTERN),
					String.format("email '%s' is illegal", registerDto.getEmail()));
			User user = userBussiness.register(registerDto.getUsername(), registerDto.getPassword(),
					registerDto.getEmail());
			if (user != null && user.getId() != null) {
				return new RestWrapper<>(true);
			}
			return new RestWrapper<>(UNKOWN_ERROR, "login failed");
		} catch (IllegalArgumentException e) {
			LOGGER.warn("register parameters error: {}", e.getMessage());
			return new RestWrapper<>(PARAM_ERROR, e.getMessage());
		} catch (BussinessException e) {
			LOGGER.warn("register occurs error: {}", e.getMessage());
			return new RestWrapper<>(e.getCode(), e.getMessage());
		} catch (Exception e) {
			LOGGER.error("register occurs system error", e);
			return new RestWrapper<>(SYSTEM_ERROR, "system is busy, please try later");
		}
	}

}
